﻿@using RazorEngine
@using System
@using System.Collections.Generic
@using EmbedXrpcIdlParser
@inherits RazorEngine.Templating.TemplateBase<CsCodeGenerater>
@{
    FileIdlInfo idlInfo = ((CsCodeGenerater)this.Model).IdlInfo;
    GenType genType = ((CsCodeGenerater)this.Model).GenType;
}
<h1 using EmbedXrpc; />
<h1 using System; />
<h1 using System.Reflection; />
<h1 using System.Collections.Generic; />
@{
    foreach (var userNs in idlInfo.GenerationOption.UserNamespace)
    {
        <h1 using @userNs ; />
    }
}
<h1 // auto code gen ! DO NOT modify this file! create time @DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") ; />
<h1 namespace @idlInfo.GenerationOption.CSharpNameSpace />
<h1 { />
@{
    var ens = idlInfo.TargetEnums;
    foreach (var enu in ens)
    {
        <h1 public enum @enu.Name :@enu.IntType />
        <h1 { />
        foreach (var ev in enu.TargetEnumValues)
        {

            <h1 @(ev.Description + "=") @(ev.Value + ",") />
        }

        <h1 } />
    }

    var structs = idlInfo.TargetStructs;
    foreach (var stru in structs)
    {
        if (stru.BitsAttribute != null)
        {
            <h1 [Bits( @("BitsType." + stru.BitsAttribute.BitsType.ToString() ) )] />
        }
        <h1 public class @stru.Name />
        <h1 { />
        foreach (var field in stru.TargetFields)
        {

            if (field.IsArray == true)
            {
                string v = "[ArrayProperty(LenFieldName = \"" + field.MaxCountAttribute.LenFieldName + "\")]";
                <h1 @v />
            }

            if (field.IsArray == true)
            {
                var lenField = IdlInfo.GetArrayLenField(stru.TargetFields, field);
                int lenv = 0;
                if (lenField == null)
                {
                    lenv = 1;
                }
                <h1 public @field.IdlType @(field.Name + "{get;set;}")=new @{ @field.ElementType  } [ @lenv ]; />
            }
            else
            {
                if (field.BitsFieldLengthAttribute != null)
                {
                    <h1 [BitsFieldLength( @field.BitsFieldLengthAttribute.Length )] />
                }
                if (field.IsBaseValueType == true && field.BitsType== BitsType.NoBits)
                {

                    <h1 public @field.IdlType @(field.Name + "{get;set;}") />
                }
                else
                {
                    <h1 public @field.IdlType @(field.Name + "{get;set;}")=new @{ @field.IdlType  } (); />
                }
            }
        }
        <h1 } />
    }

    foreach (var del in idlInfo.TargetDelegates)
    {

        TargetStruct stru = new TargetStruct();
        stru.Name = del.MethodName + "Struct";
        stru.TargetFields = del.TargetFields;
        <h1 public class @stru.Name />
        <h1 { />
        foreach (var field in stru.TargetFields)
        {
            if (field.IsArray == true)
            {
                string v = "[ArrayProperty(LenFieldName = \"" + field.MaxCountAttribute.LenFieldName + "\")]";

                <h1 @v />
            }
            if (field.IsArray == true)
            {
                var lenField = IdlInfo.GetArrayLenField(stru.TargetFields, field);
                int lenv = 0;
                if (lenField == null)
                {
                    lenv = 1;
                }
                <h1 public @field.IdlType @(field.Name + "{get;set;}")=new @{ @field.ElementType  } [ @lenv ]; />
            }
            else
            {
                if (field.IsBaseValueType == true)
                {
                    <h1 public @field.IdlType @(field.Name + "{get;set;}") />
                }
                else
                {
                    <h1 public @field.IdlType @(field.Name + "{get;set;}")=new @{ @field.IdlType  } (); />
                }
            }
        }
        <h1 } />
        if (genType == GenType.Client || genType == GenType.All)
        {
            string delattr = "[DelegateInfo(Name=\"" + del.MethodName + "\")]";
            <h1 @delattr />
            <h1 public partial class @(del.MethodName + "ClientImpl") :IDelegate />
            <h1 { />
            <h1 @("public static readonly UInt16 " + del.MethodName + "_ServiceId=" + del.ServiceId.ToString() + ";") />
            <h1 public override UInt16 GetSid(){ return @(del.MethodName + "_ServiceId") ; } />
            <h1 public override void Invoke(SerializationManager recManager) />
            <h1 { />
            <h1 Serialization serialization=new Serialization(Assembly.GetExecutingAssembly()); />
            string s = del.MethodName + "Struct request = serialization.Deserialize <" + del.MethodName + "Struct>(recManager);";
            <h1 @s />
            string pars = string.Empty;
            string externstr = string.Empty;
            for (int pi = 0; pi < del.TargetFields.Count; pi++)
            {
                var par = del.TargetFields[pi];
                pars += "request." + par.Name;
                externstr += par.IdlType + " " + par.Name;
                if (pi + 1 < del.TargetFields.Count)
                {
                    pars += ",";
                    externstr += ",";
                }

            }
            <h1 @(del.MethodName + "(" + pars + ");") />
            <h1 } />
            <h1 //public void @(del.MethodName + "(" + externstr + ");") />
            <h1 } />
        }

        if (genType == GenType.Server || genType == GenType.All)
        {
            <h1 public class @(del.MethodName + "Delegate") />
            <h1 { />
            <h1 private EmbedXrpc.Server Server; />
            <h1 public @(del.MethodName + "Delegate(EmbedXrpc.Server server)") />
            <h1 { Server=server; } />
            <h1 @("public static readonly UInt16 " + del.MethodName + "_ServiceId=" + del.ServiceId.ToString() + ";") />

            var pars = string.Empty;
            for (int pi = 0; pi < del.TargetFields.Count; pi++)
            {
                var par = del.TargetFields[pi];
                pars += par.IdlType + " " + par.Name;
                if (pi + 1 < del.TargetFields.Count)
                {
                    pars += ",";
                }

            }
            <h1 public void Invoke( @(pars) ) />
            <h1 { />
            <h1 @(del.MethodName + "Struct request")=new @(del.MethodName + "Struct();") />
            for (int pi = 0; pi < del.TargetFields.Count; pi++)
            {
                var par = del.TargetFields[pi];
                string setvalue = "request." + par.Name + "=" + par.Name + ";";
                <h1 @setvalue />
            }
            <h1 SerializationManager sm=new SerializationManager(); />
            <h1 Serialization serialization=new Serialization(Assembly.GetExecutingAssembly()); />
            <h1 serialization.Serialize(sm, request); />
            string sendBytesString = "List<byte> sendBytes = new List<byte>();";
            <h1 @sendBytesString />

            string sid_temp = "(byte)(" + del.MethodName + "_ServiceId&0xff)";
            <h1 sendBytes.Add( @sid_temp ); />

            sid_temp = "(byte)(" + del.MethodName + "_ServiceId>>8&0xff)";
            <h1 sendBytes.Add( @sid_temp ); />

            sid_temp = "(byte)(Server.TimeOut>>0&0xff)";
            <h1 sendBytes.Add( @sid_temp ); />

            sid_temp = "(byte)(Server.TimeOut>>8&0xff)";
            <h1 sendBytes.Add( @sid_temp ); />

            <h1 sendBytes.AddRange(sm.Data); />
            <h1 Server.Send ( sendBytes.Count,0,sendBytes.ToArray() ); />
            <h1 } />
            <h1 } />
        }

    }

    var interfaces = idlInfo.TargetInterfaces;

    foreach (var interf in interfaces)
    {
        foreach (var service in interf.Services)
        {
            TargetStruct stru = new TargetStruct();
            stru.Name = interf.Name + "_" + service.ServiceName + "_Request";
            stru.TargetFields = service.TargetFields;
            <h1 public class @stru.Name />
            <h1 { />
            foreach (var field in stru.TargetFields)
            {
                if (field.IsArray == true)
                {
                    string v = "[ArrayProperty(LenFieldName = \"" + field.MaxCountAttribute.LenFieldName + "\")]";

                    <h1 @v />
                }
                if (field.IsArray == true)
                {
                    var lenField = IdlInfo.GetArrayLenField(stru.TargetFields, field);
                    int lenv = 0;
                    if (lenField == null)
                    {
                        lenv = 1;
                    }
                    <h1 public @field.IdlType @(field.Name + "{get;set;}")=new @{ @field.ElementType  } [ @lenv ]; />
                }
                else
                {
                    if (field.IsBaseValueType == true)
                    {
                        <h1 public @field.IdlType @(field.Name + "{get;set;}") />
                    }
                    else
                    {
                        <h1 public @field.IdlType @(field.Name + "{get;set;}")=new @{ @field.IdlType  } (); />
                    }
                }
            }
            <h1 } />

            if (service.ReturnValue != null)
            {
                TargetStruct returnstru = new TargetStruct();
                returnstru.Name = interf.Name + "_" + service.ServiceName + "_Response";
                TargetField returnField = new TargetField() { IdlType = service.ReturnValue.IdlType, IsArray = false, Name = "ReturnValue" };
                TargetField ResponseStateField = new TargetField() { IdlType = "ResponseState", IsArray = false, Name = "State" };
                returnstru.TargetFields = new List<TargetField>() { ResponseStateField, returnField };
                <h1 public class @returnstru.Name />
                <h1 { />
                foreach (var field in returnstru.TargetFields)
                {
                    if (field.IsArray == true)
                    {
                        string v = "[ArrayProperty(LenFieldName = \"" + field.MaxCountAttribute.LenFieldName + "\")]";

                        <h1 @v />
                    }
                    <h1 public @field.IdlType @(field.Name + "{get;set;}") />
                }
                <h1 } />
            }

        }

        foreach (var service in interf.Services)
        {
            if (genType == GenType.Server || genType == GenType.All)
            {
                string serviceattr = "[ServiceInfo(Name=\"" + interf.Name + "." + service.ServiceName + "\")]";
                <h1 @serviceattr />
                <h1 public partial class @(interf.Name + "_" + service.ServiceName + "Service") :IService />
                <h1 { />
                <h1 @("public static readonly UInt16 " + service.ServiceName + "_ServiceId=" + service.ServiceId.ToString() + ";") />

                <h1 public override UInt16 GetSid(){ return @(service.ServiceName + "_ServiceId") ; } />
                if (service.ReturnValue != null)
                {
                    <h1 private @(interf.Name + "_" + service.ServiceName + "_Response Response")=new @(interf.Name + "_" + service.ServiceName + "_Response()") ; />
                }
                <h1 public override void Invoke(SerializationManager recManager, SerializationManager sendManager) />
                <h1 { />
                <h1 Serialization serialization=new Serialization(Assembly.GetExecutingAssembly()); />
                string s = interf.Name + "_" + service.ServiceName + "_Request request = serialization.Deserialize <" + interf.Name + "_" + service.ServiceName + "_Request>(recManager);";
                <h1 @s />
                string pars = string.Empty;
                string externstr = string.Empty;
                for (int pi = 0; pi < service.TargetFields.Count; pi++)
                {
                    var par = service.TargetFields[pi];
                    pars += "request." + par.Name;
                    externstr += par.IdlType + " " + par.Name;
                    if (pi + 1 < service.TargetFields.Count)
                    {
                        pars += ",";
                        externstr += ",";
                    }

                }
                <h1 @(service.ServiceName + "(" + pars + ");") />

                if (service.ReturnValue != null)
                {
                    <h1 // Serialization serialization=new Serialization(Assembly.GetExecutingAssembly()); />
                    <h1 serialization.Serialize(sendManager, Response); />
                }

                <h1 } />
                <h1 //public void @(service.ServiceName + "(" + externstr + ");") />
                <h1 } />
            }

        }
        if (genType == GenType.Client || genType == GenType.All)
        {
            foreach (var service in interf.Services)
            {
                string responseInfoattr = "[ResponseInfo(Name=\"" + interf.Name + "." + service.ServiceName + "\",ServiceId=" + service.ServiceId.ToString() + ")]";
                <h1 @responseInfoattr />
            }
            <h1 public class @(interf.Name + "ClientImpl") />
            <h1 { />
            <h1 private EmbedXrpc.Client Client=null; />
            <h1 public @(interf.Name + "ClientImpl(EmbedXrpc.Client client)") />
            <h1 { Client=client;} />

            foreach (var service in interf.Services)
            {
                <h1 @("public static readonly UInt16 " + service.ServiceName + "_ServiceId=" + service.ServiceId.ToString() + ";") />
                string pars = string.Empty;
                for (int pi = 0; pi < service.TargetFields.Count; pi++)
                {
                    var par = service.TargetFields[pi];
                    pars += par.IdlType + " " + par.Name;
                    if (pi + 1 < service.TargetFields.Count)
                    {
                        pars += ",";
                    }

                }
                if (service.ReturnValue != null)
                {
                    <h1 public @(interf.Name + "_" + service.ServiceName + "_Response") @(service.ServiceName + "(") @(pars + ")") />
                }
                else
                {
                    <h1 public void @(service.ServiceName + "(") @(pars + ")") />
                }
                <h1 { />
                <h1 lock(Client.ObjectMutex) />
                <h1 { />
                <h1 Client.ResponseMessageQueueHandle.Reset(); />
                <h1 @(interf.Name + "_" + service.ServiceName + "_Request request")=new @(interf.Name + "_" + service.ServiceName + "_Request ();") />
                for (int pi = 0; pi < service.TargetFields.Count; pi++)
                {
                    var par = service.TargetFields[pi];
                    string setvalue = "request." + par.Name + "=" + par.Name + ";";
                    <h1 @setvalue />
                }
                <h1 SerializationManager sm=new SerializationManager(); />
                <h1 Serialization serialization=new Serialization(Assembly.GetExecutingAssembly()); />
                <h1 serialization.Serialize(sm, request); />

                var sendBytesString2 = "List<byte> sendBytes = new List<byte>();";
                <h1 @sendBytesString2 />

                string sid_temp = "(byte)(" + service.ServiceName + "_ServiceId&0xff)";
                <h1 sendBytes.Add( @sid_temp ); />

                sid_temp = "(byte)(" + service.ServiceName + "_ServiceId>>8&0xff)";
                <h1 sendBytes.Add( @sid_temp ); />

                sid_temp = "(byte)(Client.TimeOut>>0&0xff)";
                <h1 sendBytes.Add( @sid_temp ); />

                sid_temp = "(byte)(Client.TimeOut>>8&0xff)";
                <h1 sendBytes.Add( @sid_temp ); />

                <h1 sendBytes.AddRange(sm.Data); />
                <h1 Client.Send ( sendBytes.Count,0,sendBytes.ToArray() ); />
                if (service.ReturnValue != null)
                {
                    <h1 @(interf.Name + "_" + service.ServiceName + "_Response response")=new @(interf.Name + "_" + service.ServiceName + "_Response()") ; />
                    <h1 ResponseState result=@("Client.Wait<"+interf.Name+"_"+service.ServiceName+ "_Response>(") @(service.ServiceName + "_ServiceId, out response);") />
                    <h1 if(response @("==null") ) />
                    <h1 { />
                    <h1 response=new @(interf.Name + "_" + service.ServiceName + "_Response()") ; />
                    <h1 } />
                    <h1 response.State=result; />
                    <h1 return response; />
                }
                <h1 } />

                <h1 } />
            }
            <h1 } />
        }
    }
}
<h1 } />
